<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xml:lang="en" lang="en">
    <head>
        <title>Binding Engine JavaScript unit test file</title>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />

        <script src="../libs/javascript-xpath-latest-cmp.js" type="text/javascript"></script>
        <script src="../src/dbe.js" type="text/javascript"></script>
        <!-- no loading of metaphorea.js lib -->

        <script src="jsunittest/jsunittest.js" type="text/javascript"></script>
        <link rel="stylesheet" href="jsunittest/unittest.css" type="text/css" />
    </head>
    <body>

        <div id="content">

            <div id="header">
                <p>tests :
                    <a href="dbe_test.html">dbe</a>
                    <a href="metaphorea_test.html">metaphorea</a>
                    <a href="metaphorea_scale_test.html">scaling</a>
                    <a href="metaphorea_interaction_test.html">interaction</a>
                    <a href="metaphorea_demo.html">demo</a>
                </p>
                <h1>dbe.js unit tests</h1>
            </div>

            <!-- Log output (one per Runner, via {testLog: "testlog"} option)-->
            <div id="testlog"></div>
            <a href="javascript:structuralTests();">structural Tests (in browser console)</a>

            <!-- Put sample/test html here -->
            <div id="sample">
            </div>
        </div>

        <script type="text/javascript">
            // <![CDATA[

            var dbe = $dbe.direct();
            var dblDoc;


            new Test.Unit.Runner({

                setup: function() {
                },

                teardown: function() {
                },


                // *** testing dbe.fun

                testDomLoadDocument: function() {
                    console.log('testDomLoadDocument:');
                    var that = this;
                    dblDoc = null;
                    // test synchronous loading
                    dblDoc = dbe.dom.loadDocument('visuals/barchart.dbl.xml');
                    that.assert(dblDoc.documentElement.nodeName === 'doc');
                    dblDoc = null;
                    // test asynchronous loading (callback provided)
                    dbe.dom.loadDocument('visuals/barchart.dbl.xml', function (xml) {
                        dblDoc = xml;
                        that.assert(dblDoc.documentElement.nodeName === 'doc');
                    });
                },
                
                testFunSet: function() {
                    console.log('testFunSet:');
                    // test fun.Set
                    var s1 = new dbe.fun.Set();
                    this.assert(s1.s.length === 0,'fun.Set check 1');

                    // test fun.Set.add
                    var ok;
                    var o1 = {};
                    this.assert(s1.size() === 0,'fun.Set.size check 1');
                    ok = s1.add(o1);
                    this.assert(s1.s.length === 1,'fun.Set.add check 1');
                    this.assert(s1.s[0] === o1,'fun.Set.add check 2');
                    this.assert(ok,'fun.Set.add check 3');
                    ok = s1.add(o1);
                    this.assert(s1.s.length === 1,'fun.Set.add check 4');
                    this.assert(s1.s[0] === o1,'fun.Set.add check 5');
                    this.assert(!ok,'fun.Set.add check 6');

                    // test fun.Set.size
                    this.assert(s1.size() === 1,'fun.Set.size check 2');
                    
                    // test fun.Set.has
                    this.assert(s1.has(o1),'fun.Set.has check 1');

                    // test fun.Set.rem
                    ok = s1.rem(o1);
                    this.assert(s1.size() === 0,'fun.Set.size check 3');
                    this.assert(!s1.has(o1),'fun.Set.rem check 1');
                    this.assert(s1.s.length === 0,'fun.Set.rem check 2');
                    this.assert(ok,'fun.Set.rem check 3');
                    ok = s1.rem(o1);
                    this.assert(!ok,'fun.Set.rem check 4');

                    // test fun.Set.each
                    var o2 = {name : 'o2'};
                    var o3 = {name : 'o3'};
                    var o = {};
                    s1.add(o2);
                    s1.add(o3);
                    s1.each(function(item) {o[item.name] = item;});
                    this.assert(o['o2'] === o2,'fun.Set.each check 1');
                    this.assert(o['o3'] === o3,'fun.Set.each check 2');

                    // test fun.Set.union
                    var s2 = new dbe.fun.Set();
                    var o4 = {name : 'o4'};
                    var o5 = {name : 'o5'};
                    s2.add(o3);
                    s2.add(o4);
                    s2.add(o5);
                    var su = s1.union(s2);
                    this.assert(su.s.length === 4,'fun.Set.union check 1');
                    this.assert(!su.has(o1),'fun.Set.union check 2');
                    this.assert(su.has(o2),'fun.Set.union check 3');
                    this.assert(su.has(o3),'fun.Set.union check 4');
                    this.assert(su.has(o4),'fun.Set.union check 5');
                    this.assert(su.has(o5),'fun.Set.union check 6');

                    // test fun.Set.inter
                    var si = s1.inter(s2);
                    this.assert(si.s.length === 1,'fun.Set.inter check 1');
                    this.assert(si.has(o3),'fun.Set.inter check 2');

                    // test fun.Set.sub
                    var ss = s1.sub(s2);
                    this.assert(ss.s.length === 1,'fun.Set.sub check 1');
                    this.assert(!ss.has(o3),'fun.Set.sub check 2');
                    this.assert(ss.has(o2),'fun.Set.sub check 3');
                },

                testEvtEvents: function() {
                    console.log('testEvtEvents:');
                    // test Event
                    var e1 = new dbe.evt.Event('typeA');
                    var e2 = new dbe.evt.Event('typeC');
                    this.assert(!e1.is(''),'event.is check 1');
                    this.assert(e1.is('typeA'),'event.is check 2');
                    this.assert(!e1.is('typeB'),'event.is check 3');
                    this.assert(!e1.is('typeC'),'event.is check 4');
                    this.assert(!e2.is(''),'event.is check 5');
                    this.assert(!e2.is('typeA'),'event.is check 6');
                    this.assert(!e2.is('typeB'),'event.is check 7');
                    this.assert(e2.is('typeC'),'event.is check 8');
                    this.assert(e1.uid === 0,'event.uid check 1');
                    this.assert(e2.uid === 1,'event.uid check 2');
                    // test EventHandler
                    var o1 = {};
                    this.assert(!o1.events,'EventHandler construction check 1');
                    o1.events = new dbe.evt.EventHandler(o1);
                    this.assert(o1.events,'EventHandler construction check 2');
                    o1.flag = false;
                    o1.events.on('typeA',function (ev) {o1.flag = true;});
                    o1.events.on('typeC',function (ev) {o1.flag = false;});
                    this.assert(o1.flag === false,'events.fire check 1');
                    o1.events.fire(e1);
                    this.assert(o1.flag === true,'events.fire check 2');
                    o1.events.fire('typeC');
                    this.assert(o1.flag === false,'events.fire check 3');
                    o1.events.fire('typeA');
                    this.assert(o1.flag === true,'events.fire check 4');
                    o1.events.fire('typeA');
                    this.assert(o1.flag === true,'events.fire check 5');
                    var e3 = new dbe.evt.Event('typeB typeD',o1);
                    this.assert(e3.uid === 5,'event.uid check 3');
                    this.assert(e3.target === o1,'event.target check');
                },

                // *** testing dbe.dbl
                
                testDblN: function() {
                    console.log('testDblN:');
                    dblDoc = dbe.dom.loadDocument('visuals/barchart.dbl.xml');
                    var xmlElt = dblDoc.documentElement;
                    // test dbl.N
                    var dblN = new dbe.dbl.N(xmlElt,null,null);
                    var dblN0 = new dbe.dbl.N(null,null,null);
                    // test dbl.N.type
                    this.assert(dblN.type() === 'doc','dbl.N.type check 1');
                    this.assert(dblN0.type() === dbe.dbl.BIND,'dbl.N.type check 2');
                    // test dbl.N.is
                    this.assert(dblN.is(dbe.dbl.DOC),'dbl.Node.is doc');
                    this.assert(dblN0.is(dbe.dbl.BIND),'dbl.Node.is bind');
                    this.assert(dblN.xmlElt === xmlElt,'dbl.Node constructor doesnt set xmlElt member');
                    // test dbl.N.get
                    this.assert(dblN.get('id') === 'barchart','dbl.DocNode.get param which exists');
                    this.assert(dblN.get('min') === '1','dbl.DocNode.get param which doesnt exist');
                    // test dbl.N.set
                    dblN.set('min','2');
                    this.assert(dblN.get('min') === '2','dbl.DocNode.set param');
                    dblN.set('id','newid');
                    this.assert(dblN.get('id') === 'newid','dbl.DocNode.set param');
                    // test dbl.N.defaults
                    this.assert(dblN.defaults.min === '1','dbl.DocNode.defaults');
                    // testing sub construction
                    this.assert(dblN.dblNs[dbe.dbl.ELT].size() === 1,'dbl.DocNode.dblNodes access');
                    // test dbl.N.addDblN
                    this.assert(dblN.dblNs[dbe.dbl.BIND].size() === 0,'dbl.N.addDblN check 1');
                    dblN.addDblN(dblN0);
                    this.assert(dblN.dblNs[dbe.dbl.BIND].size() === 1,'dbl.N.addDblN check 2');
                },

                testOpScope: function() {
                    console.log('testOpScope:');
                    var o1 = {
                        name : 'o1',
                        scope : new dbe.op.Scope(null)
                    }
                    var s1a = new dbe.fun.Set();
                    // test op.Scope.set
                    o1.scope.set('a',s1a);
                    // test op.Scope.get
                    this.assert(o1.scope.get('a') === s1a,'op.Scope.set check 1');
                    this.assert(o1.scope.get('dummy').size() === 0,'op.Scope.set check 2');
                    var o1a1 = {
                        name : 'o1a1',
                        scope : new dbe.op.Scope(o1.scope)
                    }
                    s1a.add(o1a1);
                    // test op.Scope & parScope
                    this.assert(o1a1.scope.get('a') === o1.scope.get('a'),'op.Scope parScope check 1');
                    var o1a2 = {
                        name : 'o1a2',
                        scope : new dbe.op.Scope(o1.scope)
                    }
                    s1a.add(o1a2);
                    this.assert(o1a1.scope.get('a').size() === 2,'op.Scope parScope check 2');

                    // test op.Scope linkage & homonymy
                    var o1a2a1 = {
                        name : 'o1a2a1',
                        scope : new dbe.op.Scope(o1a2.scope)
                    }
                    var s1a2a = new dbe.fun.Set();
                    s1a2a.add(o1a2a1);
                    o1a2.scope.set('a',s1a2a);
                    this.assert(o1a2.scope.get('a') === s1a2a,'op.Scope homonymy check 0');
                    this.assert(o1a2.scope.get('a') !== o1a1.scope.get('a'),'op.Scope homonymy check 1');
                    this.assert(o1a2.scope.get('a') !== o1.scope.get('a'),'op.Scope homonymy check 2');
                    this.assert(o1a2.scope.get('a').size() === o1.scope.get('a.a').size(),'op.Scope linkage check 1');
                    this.assert(o1a2.scope.get('a').has(o1a2a1) === o1.scope.get('a.a').has(o1a2a1),'op.Scope linkage check 2');
                    // test op.Scope unset
                    o1a2.scope.unset('a');
                    this.assert(o1a2.scope.get('a') === s1a,'op.Scope unset 1');
                    this.assert(o1.scope.get('a.a').size() === 0,'op.Scope unset 2');
                    this.assert(!o1a2.scope.bag['a'],'op.Scope unset 3');
                    this.assert(!o1a2.scope.bag.hasOwnProperty('a'),'op.Scope unset 4');
                    // test op.Scope add
                    var v1 = {};
                    this.assert(o1a2.scope.get('v1').size() === 0,'op.Scope add check 1');
                    o1a2.scope.add('v1',v1);
                    this.assert(o1a2.scope.get('v1').has(v1),'op.Scope add check 2');
                },

                testOpState: function() {
                    console.log('testOpState:');
                    var o1 = {
                        name : 'o1',
                        state : new dbe.op.State(this)
                    }
                    this.assert(o1.state.isToUpdate(),'op.State check 1');
                    this.assert(!o1.state.isUpdated(),'op.State check 2');
                    this.assert(!o1.state.isUpdating(),'op.State check 3');
                    this.assert(o1.state.updateCount === 0,'op.State check 4');
                    this.assert(o1.state.updateStamp === null,'op.State check 5');
                    this.assert(o1.state.dirty,'op.State check 6');
                    o1.state.nowUpdating();
                    this.assert(!o1.state.isToUpdate(),'op.State check 6');
                    this.assert(!o1.state.isUpdated(),'op.State check 7');
                    this.assert(o1.state.isUpdating(),'op.State check 8');
                    this.assert(!o1.state.dirty,'op.State check 9');
                    o1.state.nowUpdated();
                    this.assert(!o1.state.isToUpdate(),'op.State check 11');
                    this.assert(o1.state.isUpdated(),'op.State check 12');
                    this.assert(!o1.state.isUpdating(),'op.State check 13');
                    this.assert(o1.state.updateCount === 1,'op.State check 14');
                    this.assert(o1.state.updateStamp !== null,'op.State check 15');
                    this.assert(!o1.state.dirty,'op.State check 16');
                    o1.state.nowDirty();
                    this.assert(o1.state.isToUpdate(),'op.State check 21');
                    this.assert(!o1.state.isUpdated(),'op.State check 22');
                    this.assert(!o1.state.isUpdating(),'op.State check 23');
                    this.assert(o1.state.updateCount === 1,'op.State check 24');
                    this.assert(o1.state.updateStamp !== null,'op.State check 25');
                    this.assert(o1.state.dirty,'op.State check 26');
                    o1.state.nowUpdating();
                    this.assert(!o1.state.isToUpdate(),'op.State check 26');
                    this.assert(!o1.state.isUpdated(),'op.State check 27');
                    this.assert(o1.state.isUpdating(),'op.State check 28');
                    this.assert(!o1.state.dirty,'op.State check 29');
                    o1.state.nowDirty();
                    this.assert(!o1.state.isToUpdate(),'op.State check 31');
                    this.assert(!o1.state.isUpdated(),'op.State check 32');
                    this.assert(o1.state.isUpdating(),'op.State check 33');
                    this.assert(o1.state.updateCount === 1,'op.State check 34');
                    this.assert(o1.state.updateStamp !== null,'op.State check 35');
                    this.assert(o1.state.dirty,'op.State check 36');
                    o1.state.nowUpdated(); // but dirty
                    this.assert(o1.state.isToUpdate(),'op.State check 41');
                    this.assert(!o1.state.isUpdated(),'op.State check 42');
                    this.assert(!o1.state.isUpdating(),'op.State check 43');
                    this.assert(o1.state.updateCount === 2,'op.State check 44');
                    this.assert(o1.state.updateStamp !== null,'op.State check 45');
                    this.assert(o1.state.dirty,'op.State check 46');

                    
                },

                testOpB: function() {
                    console.log('testOpB:');
                    // test op.B
                    var parOpBQ = {
                        addedOpB : false,
                        scope : new dbe.op.Scope(),
                        addOpB : function (opB) {this.addedOpB = true;},
                        completeOpB : function(opB) {opB.isComplete = true}
                    };
                    new dbe.evt.EventHandler(parOpBQ);
                    var dblB = new dbe.dbl.N(null,null,null);
                    this.assert(parOpBQ.addedOpB === false,'op.B check check 1');
                    var opB = new dbe.op.B(dblB,parOpBQ);
                    this.assert(opB.parOpBQ === parOpBQ,'op.B check 2');
                    this.assert(opB.parOpBQ.scope === opB.scope.parScope,'op.B check 3');
                    this.assert(parOpBQ.addedOpB === true,'op.B check 4');
                    // test op.B.addOpN
                    var opN = {adapt : function(){},getMatchKey  : function(){return '';}};
                    var opN2 = {adapt : function(){},getMatchKey : function(){return '';}};
                    var opN3 = {adapt : function(){},getMatchKey : function(){return '';}};
                    var opN4 = {adapt : function(){},getMatchKey : function(){return '';}};
                    opN.events = new dbe.evt.EventHandler(opN);
                    opN2.events = new dbe.evt.EventHandler(opN2);
                    opN3.events = new dbe.evt.EventHandler(opN3);
                    opN4.events = new dbe.evt.EventHandler(opN4);
                    var dblN2 = {v : {max : 3, min : 2}, get : function(arg){return this.v[arg];}}
                    var opNQ2 = {getId : function(){return 'myid';},shortId : function(){return 'myid';},dblN:dblN2};
                    var res = opB.addOpN(opN2,opNQ2);
                    this.assert(opB.opNs.myid.size() === 1,'op.B.addOpN check 1');
                    this.assert(res === true,'op.B.addOpN check 2');
                    res = opB.addOpN(opN2,opNQ2);
                    this.assert(opB.opNs.myid.size() === 1,'op.B.addOpN check 3');
                    this.assert(res === false,'op.B.addOpN check 4');
                    res = opB.addOpN(opN,opNQ2);
                    this.assert(opB.opNs.myid.size() === 2,'op.B.addOpN check 5');
                    this.assert(res === true,'op.B.addOpN check 6');
                    res = opB.addOpN(opN3,opNQ2);
                    this.assert(opB.opNs.myid.size() === 2,'op.B.addOpN check 7');
                    this.assert(res === false,'op.B.addOpN check 8');
                    res = opB.addOpN(opN3,opNQ2,true);
                    this.assert(opB.opNs.myid.size() === 3,'op.B.addOpN check 9');
                    this.assert(res === true,'op.B.addOpN check 10');
                    res = opB.addOpN(opN4,opNQ2);
                    this.assert(opB.opNs.myid.size() === 3,'op.B.addOpN check 11');
                    this.assert(res === false,'op.B.addOpN check 12');
                    res = opB.addOpN(opN4,opNQ2,true);
                    this.assert(opB.opNs.myid.size() === 3,'op.B.addOpN check 13');
                    this.assert(res === false,'op.B.addOpN check 14');
                    // TOOD test op.B.addOpBQ
                    var opBQ = {};
                    this.assert(opB.opBQs.size() === 0,'op.B.addOpBQ check 1');
                    opB.addOpBQ(opBQ);
                    this.assert(opB.opBQs.size() === 1,'op.B.addOpBQ check 2');
                    var opBQ2 = {};
                    opB.addOpBQ(opBQ2);
                    this.assert(opB.opBQs.size() === 2,'op.B.addOpBQ check 3');
                    // TOOD test op.B.remOpBQ
                    opB.remOpBQ(opBQ);
                    this.assert(opB.opBQs.size() === 1,'op.B.remOpBQ check 1');
                    opB.remOpBQ(opBQ);
                    this.assert(opB.opBQs.size() === 1,'op.B.remOpBQ check 2');
                    opB.remOpBQ(opBQ2);
                    this.assert(opB.opBQs.size() === 0,'op.B.remOpBQ check 3');
                    // TODO test op.B.buildOpBQs
                    // TODO test op.B.match
                },

                testOpRenewRootOpB: function() {
                    console.log('testOpRenewRootOpB:');
                    var rootOpB = dbe.op.rootOpB;
                    this.assert(rootOpB,'op.rootOpB init check');
                    dbe.op.renewRootOpB();
                    this.assert(rootOpB !== dbe.op.rootOpB,'op.renewRootOpB check 1');
                    this.assert(rootOpB.dblB.get('id') === 'ROOT','op.rootOpB dblB check 1');
                },

                testOpBQ: function() {
                    console.log('testOpBQ:');
                    // test op.BQ
                    dblDoc = dbe.dom.loadDocument('bindings/sample_binding_multi.xml');
                    var xmlElt = dblDoc.documentElement;
                    var dblB = new dbe.dbl.N(xmlElt,null);
                    var parOpB = {
                        addedOpBQ : false,
                        scope : new dbe.op.Scope(),
                        addOpBQ : function (opBQ) {this.addedOpBQ = true;}
                    };
                    this.assert(parOpB.addedOpBQ === false,'op.BQ check 1');
                    var opBQ = new dbe.op.BQ(dblB,parOpB);
                    this.assert(opBQ.parOpB === parOpB,'op.BQ check 2');
                    this.assert(opBQ.parOpB.scope === opBQ.scope.parScope,'op.BQ check 3');
                    this.assert(parOpB.addedOpBQ === true,'op.BQ check 4');

                    // test op.BQ.addOpB
                    this.assert(opBQ.opBs.size() === 0, 'op.BQ.addOpB check 1');
                    var opB = {};
                    opB.events = new dbe.evt.EventHandler(opB);
                    this.assert(opBQ.opBs.has(opB) === false, 'op.BQ.addOpB check 2');
                    opBQ.addOpB(opB);
                    this.assert(opBQ.opBs.size() === 1, 'op.BQ.addOpB check 3');
                    this.assert(opBQ.opBs.has(opB) === true, 'op.BQ.addOpB check 4');

                    // test op.BQ.remOpB
                    opBQ.remOpB({});
                    this.assert(opBQ.opBs.size() === 1, 'op.BQ.remOpB check 1');
                    this.assert(opBQ.opBs.has(opB) === true, 'op.BQ.remOpB check 2');
                    opBQ.remOpB(opB);
                    this.assert(opBQ.opBs.size() === 0, 'op.BQ.remOpB check 3');
                    this.assert(opBQ.opBs.has(opB) === false, 'op.BQ.remOpB check 4');

                    // TODO test op.BQ.bindOpN
                    

                    // test op.BQ.addOpNQ
                    var opNQ = {
                        getId : function() {return 'myid';},
                        opNs : new dbe.fun.Set()
                    };
                    opNQ.opNs.add({});
                    opNQ.events = new dbe.evt.EventHandler(opNQ);
                    var c = opBQ.opNQs.size();
                    this.assert(opBQ.opNQs.size() === c, 'op.BQ.addOpNQ check 1');
                    this.assert(opBQ.opNQs.has(opNQ) === false, 'op.BQ.addOpNQ check 2');
                    opBQ.addOpNQ(opNQ);
                    this.assert(opBQ.opNQs.size() === c+1, 'op.BQ.addOpB addOpNQ check 3');
                    this.assert(opBQ.opNQs.has(opNQ) === true, 'op.BQ.addOpNQ check 4');
                    this.assert(opBQ.scope.get('myid') === opNQ.opNs,'op.BQ.addOpNQ check 5');
                    this.assert(opBQ.scope.get('myid').size() === 1,'op.BQ.addOpNQ check 6');
                    
                    // test op.BQ.remOpNQ
                    opBQ.remOpNQ({});
                    this.assert(opBQ.opNQs.size() === c+1, 'op.BQ.remOpNQ check 1');
                    this.assert(opBQ.opNQs.has(opNQ) === true, 'op.BQ.remOpNQ check 2');
                    opBQ.remOpNQ(opNQ);
                    this.assert(opBQ.opNQs.size() === c, 'op.BQ.remOpNQ check 3');
                    this.assert(opBQ.opNQs.has(opNQ) === false, 'op.BQ.remOpNQ check 4');
                    this.assert(opBQ.scope.get('myid').size() === 0,'op.BQ.remOpNQ check 5');

                    // TODO test op.BQ.buildOpNQs


                },

                testOpNQ: function() {
                    console.log('testOpNQ:');
                    // test op.NQ
                    dblDoc = dbe.dom.loadDocument('visuals/barchart.dbl.xml');
                    var xmlElt = dblDoc.documentElement;
                    var dblN = new dbe.dbl.N(xmlElt,null,null);
                    var parOp = {
                        scope : new dbe.op.Scope(),
                        addedOpNQ : false,
                        addOpNQ   : function(opNQ) {this.addedOpNQ = true;}
                    };
                    this.assert(parOp.addedOpNQ === false,'op.NQ check 1');
                    var opNQ = new dbe.op.NQ(dblN,parOp);
                    this.assert(opNQ.parOp === parOp,'op.NQ check 2');
                    this.assert(opNQ.parOp.scope === opNQ.scope.parScope,'op.NQ check 3');
                    this.assert(parOp.addedOpNQ === true,'op.NQ check 4');

                    // test op.NQ.is
                    this.assert(opNQ.is(dbe.dbl.DOC),'op.NQ.is check 1');
                    this.assert(!opNQ.is(dbe.dbl.BIND),'op.NQ.is check 2');

                    // test op.NQ.isRef
                    this.assert(!opNQ.isRef(),'op.NQ.isRef check 1');
                    opNQ.dblN.set('ref','dummy');
                    this.assert(opNQ.isRef(),'op.NQ.isRef check 2');
                    opNQ.dblN.set('ref','');
                    this.assert(!opNQ.isRef(),'op.NQ.isRef check 3');

                    // test op.NQ.getId
                    this.assert(opNQ.getId() === 'barchart','op.NQ.getId check 1');

                    // test op.NQ.addOpN
                    var opN = {};
                    var cSize = opNQ.opNs.size();
                    opNQ.addOpN(opN);
                    this.assert(opNQ.opNs.size() === cSize+1,'op.NQ.addOpN check 1');

                    // test op.NQ.remOpN
                    opNQ.remOpN(opN);
                    this.assert(opNQ.opNs.size() === cSize,'op.NQ.remOpN check 1');

                    // TODO test op.NQ.update
                    
                },

                testOpN: function() {
                    // TODO debug
                    /*
                    console.log('testOpN:');
                    // test op.N
                    var parOpNQ = {
                        scope : new dbe.op.Scope(),
                        addedOpN : false,
                        addOpN   : function(opN) {this.addedOpN = true;}
                    };
                    dblDoc = dbe.dom.loadDocument('visuals/barchart.dbl.xml');
                    var xmlElt = dblDoc.documentElement;
                    var dblN = new dbe.dbl.N(xmlElt,null,null);
                    dblDoc = dbe.dom.loadDocument('visuals/barchart.svg');
                    var domN = dblDoc.documentElement;
                    this.assert(parOpNQ.addedOpN === false,'op.N check 0');
                    var opN = new dbe.op.N(dblN, parOpNQ, domN);
                    this.assert(opN.dblN === dblN,'op.N check 1');
                    this.assert(opN.parOpNQ === parOpNQ,'op.N check 2');
                    this.assert(opN.scope.parScope === parOpNQ.scope,'op.N check 3');
                    this.assert(opN.domN === domN,'op.N check 4');
                    this.assert(parOpNQ.addedOpN === true,'op.N check 5');

                    // test op.N.addOpNQ
                    var opNQ = {
                        getId : function() {return 'myid';},
                        opNs : new dbe.fun.Set()
                    };
                    opNQ.opNs.add({});
                    new dbe.evt.EventHandler(opNQ);
                    this.assert(opN.opNQs.size() === 1, 'op.N.addOpNQ check 1');
                    this.assert(opN.opNQs.has(opNQ) === false, 'op.N.addOpNQ check 2');
                    opN.addOpNQ(opNQ);
                    this.assert(opN.opNQs.size() === 2, 'op.N.addOpB addOpNQ check 3');
                    this.assert(opN.opNQs.has(opNQ) === true, 'op.N.addOpNQ check 4');
                    this.assert(opN.scope.get('myid') === opNQ.opNs,'op.N.addOpNQ check 5');
                    this.assert(opN.scope.get('myid').size() === 1,'op.N.addOpNQ check 6');
                    
                    // test op.N.remOpNQ
                    opN.remOpNQ({});
                    this.assert(opN.opNQs.size() === 2, 'op.N.remOpNQ check 1');
                    this.assert(opN.opNQs.has(opNQ) === true, 'op.N.remOpNQ check 2');
                    opN.remOpNQ(opNQ);
                    this.assert(opN.opNQs.size() === 1, 'op.N.remOpNQ check 3');
                    this.assert(opN.opNQs.has(opNQ) === false, 'op.N.remOpNQ check 4');
                    this.assert(opN.scope.get('myid').size() === 0,'op.N.remOpNQ check 5');
                    */
                    // TODO test op.N.buildOpNQs

                    // TODO test op.N.getValue

                    // TODO test op.N.setValue

                    // TODO test op.N.adapt

                },

                testOpAddRootBinding: function() {
                    // done in structuralUTest under
                },

                testApiAddBinding: function() {
                    console.log('testApiAddBinding:');
                    // TODO test api.addBinding
                },

                testApiReset: function() {
                    console.log('testApiReset:');
                    // TODO test api.reset
                },

                // *** closing tests
                testsPrepareStructuralUTests: function() {
                    console.log('testsPrepareStructuralUTests:');
                    dbe.op.renewRootOpB();
                    var rootOpB = dbe.op.rootOpB;
                    console.profile();
                    dbe.op.addRootBinding('bindings/sample_binding_multi.xml');
                }

            });

            var structuralTests = function() {
                console.profileEnd();
                console.log('structuralTests:');
                var rootOpB = dbe.op.rootOpB;
                console.assert(rootOpB.dblB.dblNs[dbe.dbl.BIND].size() === 1,'structTest 1');
                console.assert(rootOpB.opBQs.size() === 1,'structTest 2');
                var opBQ = rootOpB.opBQs.s[0];
                console.assert(opBQ.opNQs.size() === 4,'structTest 3');
                var i = 1;
                console.log('opBQ',opBQ);
                opBQ.opNQs.each(function(opNQ) {
                    console.log('opNQ',opNQ);
                    console.assert(opNQ.opNs.size() === 1,'structTest 10a'+i);
                    console.assert(opNQ.is(dbe.dbl.DOC),'structTest 10b'+i);
                    i++;
                });
                console.assert(opBQ.opBs.size() === 1,'structTest 20');
                var opB = opBQ.opBs.first();
                console.assert(opB.opNs['barchart'].size() === 1,'structTest 21');
                console.assert(opB.opNs['wordplot'].size() === 1,'structTest 22');
                console.assert(opB.opNs['dotplot'].size() === 1,'structTest 23');
                console.assert(opB.opNs['data'].size() === 1,'structTest 24');
                console.assert(opB.scope.get('barchart').size() === 1,'structTest 25');
                console.assert(opB.scope.get('wordplot').size() === 1,'structTest 26');
                console.assert(opB.scope.get('dotplot').size() === 1,'structTest 27');
                console.assert(opB.scope.get('data').size() === 1,'structTest 28');
                console.assert(opB.scope.get('data').first() === opB.opNs['data'].first(),'structTest 29');
                console.assert(opB.opBQs.size() === 1,'structTest 29',opB.opBQs);

                var dataOpN = opB.scope.get('data').first();
                var items = dataOpN.scope.get('item');
                console.assert(items.union,'structTest 30');
                console.assert(items.size() === 10,'structTest 31');
                var item = items.first();
                console.log('item',item);
                console.assert(item.scope.get('x').size() === 1,'structTest 32');
                console.assert(item.scope.get('y').size() === 1,'structTest 33');
                console.assert(item.scope.get('city').size() === 1,'structTest 34');

                console.assert(opB.opBQs.size() === 1,'structTest 40');
                var opBQ2 = opB.opBQs.first();
                console.assert(opBQ2.opBs.size() === 10,'structTest 41',opBQ2.opBs.size(),opBQ2);
                var opB2 = opBQ2.opBs.first();
                console.assert(opB2.opNs['data.item'],'structTest 42',opB2.opNs);
                console.assert(opB2.opNs['dotplot.dot'],'structTest 43',opB2.opNs);
                console.assert(opB2.opNs['wordplot.word'],'structTest 44',opB2.opNs);
                console.assert(opB2.opNs['barchart.bar'],'structTest 45',opB2.opNs);
                console.assert(opB2.opNs['data.item'].size() === 1,'structTest 46',opB2.opNs);
                console.assert(opB2.opNs['dotplot.dot'].size() === 1,'structTest 47',opB2.opNs);
                console.assert(opB2.opNs['wordplot.word'].size() === 1,'structTest 48',opB2.opNs);
                console.assert(opB2.opNs['barchart.bar'].size() === 1,'structTest 49',opB2.opNs);
                for (var i=0;i<opBQ2.opBs.size();i++) {
                    var opBi = opBQ2.opBs.s[i];
                    console.assert(opBi.opNs['data.item'],'structTest 50a'+i,opBi);
                    console.assert(opBi.opNs['dotplot.dot'],'structTest 50b'+i,opBi);
                    console.assert(opBi.opNs['wordplot.word'],'structTest 50c'+i,opBi);
                    console.assert(opBi.opNs['barchart.bar'],'structTest 50d'+i,opBi);
                    console.assert(opBi.opNs['data.item'].size() === 1,'structTest 50e'+i,opBi);
                    console.assert(opBi.opNs['dotplot.dot'].size() === 1,'structTest 50f'+i,opBi);
                    console.assert(opBi.opNs['wordplot.word'].size() === 1,'structTest 50g'+i,opBi);
                    console.assert(opBi.opNs['barchart.bar'].size() === 1,'structTest 50h'+i,opBi);
                }
                console.assert(opB.scope.get('data').first() === opB.scope.get('data').first(),'structTest 51');
                console.assert(opB.scope.get('barchart').first() === opB.scope.get('barchart').first(),'structTest 52');
                console.assert(opB2.scope.get('data.item').first() === opB2.opNs['data.item'].first(),'structTest 53');
                console.assert(opB2.scope.get('item').first() === opB2.opNs['data.item'].first(),'structTest 54');

                console.assert(opB2.opBQs.size() === 4,'structTest 60');
                var opBQ3 = opB2.opBQs.s[0];
                console.assert(opBQ3.opNQs.size() === 5,'structTest 61');
                console.assert(opBQ3.opBs.size() === 1,'structTest 62',opBQ3.opBs.size(),opBQ3,opBQ3.dblB.xmlElt);

                var opB4 = opBQ3.opBs.s[0];
                console.assert(opB4.opNs['item.x'],'structTest 63');
                console.assert(opB4.opNs['word.x'],'structTest 64');
                console.assert(opB4.opNs['dot.cx'],'structTest 65');
                console.assert(opB4.opNs['bar.height'],'structTest 66');
                console.assert(opB4.opNs['bar.y'],'structTest 67');
                console.assert(opB2.scope.get('item').first() === opB4.scope.get('item').first() ,'structTest 68');
                console.assert(opB4.scope.get('item.x').first() === opB4.opNs['item.x'].first(),'structTest 69a');
                console.assert(opB4.scope.get('x').first() === opB4.opNs['item.x'].first(),'structTest 69b');

                console.log('structuralTests:DONE');
                console.log('dbe',dbe);
                console.log('opB',opB);
                console.log('data',dataOpN);
                console.log('items',items);
                console.log('item',item);
                console.log('opBQ2',opBQ2);
                console.log('opB2',opB2);
                console.log('opBQ3',opBQ3);
                console.log('opB4',opB4);


            };

            // ]]>
        </script>
    </body>
</html>